/*
 * Famon (http://code.google.com/p/famon/)
 * Copyright (c) 2010 Carl Crous.
 *
 * This file is part of Famon.
 *
 * Famon is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Famon is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Famon.  If not, see <http://www.gnu.org/licenses/>.
 */

package za.org.foobar.famon.frontend.server.data;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gwtportlets.portlet.smartgwt.client.DataTransferObject;
import org.gwtportlets.portlet.smartgwt.client.SmartPortletFactory;
import org.gwtportlets.portlet.smartgwt.server.DataProviderObject;
import org.gwtportlets.portlet.smartgwt.server.SmartComparator;
import za.org.foobar.famon.frontend.client.dto.PropertyDto;
import za.org.foobar.famon.model.Property;
import za.org.foobar.famon.util.DB;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 *
 */
public class PropertyDpo implements DataProviderObject {
    private final Log log = LogFactory.getLog(getClass());
    private static PropertyDpo instance;

    public static PropertyDpo get() {
        return instance != null ? instance : (instance = new PropertyDpo());
    }

    public String getDataSourceId() {
        return PropertyDto.DATA_SOURCE_ID;
    }

    public List<DataTransferObject> fetchData(SmartPortletFactory f) {
        log.info("Getting Property data");
        List<PropertyDto> list = getPropertyDtoList(DB.createDBQuery(Property.class)
                .addOrderBy("name")
                .getResultList());
        if (f.getSort() != null) {
            log.info("Sorting");
            Collections.sort(list, new SmartComparator<PropertyDto>(PropertyDto.class, f.getSort()));
        }

        return f.limitList(list);
    }

    public DataTransferObject updateData(SmartPortletFactory f) {
        log.info("Doing update");
        PropertyDto dto = (PropertyDto)f.getSingleDto();
        if (dto != null && dto.id != null) {
            Key key = KeyFactory.stringToKey(dto.id);
            Property p = DB.find(Property.class, key);
            p.setName(dto.name);
            p.setValue(dto.value);
            DB.persist(p);
            DB.closePM();
        }
        return dto;
    }

    public DataTransferObject addData(SmartPortletFactory f) {
        log.info("Doing update");
        PropertyDto dto = (PropertyDto)f.getSingleDto();
        if (dto != null) {
            Property p = getProperty(dto);
            DB.persist(p);
            DB.closePM();
        }
        return dto;
    }

    public DataTransferObject removeData(SmartPortletFactory f) {
        log.info("Doing update");
        PropertyDto dto = (PropertyDto)f.getSingleDto();
        if (dto != null && dto.id != null) {
            Key key = KeyFactory.stringToKey(dto.id);
            Property p = DB.find(Property.class, key);
            DB.remove(p);
            DB.closePM();
        }
        return dto;
    }

    public List<PropertyDto> getPropertyDtoList(List<Property> list) {
        List<PropertyDto> dtoList = new ArrayList<PropertyDto>();
        for (Property p : list) {
            dtoList.add(getPropertyDto(p));
        }
        return dtoList;
    }

    public PropertyDto getPropertyDto(Property property) {
        PropertyDto dto = new PropertyDto();
        dto.id = KeyFactory.keyToString(property.getId());
        dto.name = property.getName();
        dto.value = property.getValue();
        return dto;
    }


    public Property getProperty(PropertyDto dto) {
        Property property = new Property();
        property.setName(dto.name);
        property.setValue(dto.value);
        return property;
    }
}
